//
//  NSString+Ext.m
//  QieyouVisitorKit
//
//  Created by 李赛强 on 15/3/31.
//  Copyright (c) 2015年 lisaiqiang. All rights reserved.
//

#import "NSString+Ext.h"
#import <CommonCrypto/CommonDigest.h>

@implementation NSString (Ext)

// Checking if String is Empty
-(BOOL)isBlank {
    return ([[self removeWhiteSpacesFromString] isEqualToString:@""]) ? YES : NO;
}
//Checking if String is empty or nil
-(BOOL)isValid {
    return ([[self removeWhiteSpacesFromString] isEqualToString:@""] || self == nil || [self isEqualToString:@"(null)"]|| [self isEqualToString:@"<null>"] || [self isEqual:[NSNull null]] || [self isKindOfClass:[NSNull class]]) ? NO :YES;
}

// remove white spaces from String
- (NSString *)removeWhiteSpacesFromString {
    NSString *trimmedString = [self stringByTrimmingCharactersInSet:
                               [NSCharacterSet whitespaceAndNewlineCharacterSet]];
    return trimmedString;
}

// Counts number of Words in String
- (NSUInteger)countNumberOfWords{
    NSScanner *scanner = [NSScanner scannerWithString:self];
    NSCharacterSet *whiteSpace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
    
    NSUInteger count = 0;
    while ([scanner scanUpToCharactersFromSet: whiteSpace  intoString: nil]) {
        count++;
    }
    
    return count;
}

// If string contains substring
- (BOOL)containsString:(NSString *)subString{
    return ([self rangeOfString:subString].location == NSNotFound) ? NO : YES;
}

// If my string starts with given string
- (BOOL)isBeginsWith:(NSString *)string{
    return ([self hasPrefix:string]) ? YES : NO;
}

// If my string ends with given string
- (BOOL)isEndssWith:(NSString *)string{
    return ([self hasSuffix:string]) ? YES : NO;
}



// Replace particular characters in my string with new character
- (NSString *)replaceCharcter:(NSString *)olderChar withCharcter:(NSString *)newerChar{
    return  [self stringByReplacingOccurrencesOfString:olderChar withString:newerChar];
}

// Get Substring from particular location to given lenght
- (NSString*)getSubstringFrom:(NSInteger)begin to:(NSInteger)end{
    NSRange r;
    r.location = begin;
    r.length = end - begin;
    return [self substringWithRange:r];
}

// Add substring to main String
- (NSString *)addString:(NSString *)string{
    if(!string || string.length == 0)
        return self;
    
    return [self stringByAppendingString:string];
}

// Remove particular sub string from main string
-(NSString *)removeSubString:(NSString *)subString{
    if ([self containsString:subString])
    {
        NSRange range = [self rangeOfString:subString];
        return  [self stringByReplacingCharactersInRange:range withString:@""];
    }
    return self;
}


// If my string contains ony letters
- (BOOL)containsOnlyLetters{
    NSCharacterSet *letterCharacterset = [[NSCharacterSet letterCharacterSet] invertedSet];
    return ([self rangeOfCharacterFromSet:letterCharacterset].location == NSNotFound);
}

// If my string contains only numbers
- (BOOL)containsOnlyNumbers{
    NSCharacterSet *numbersCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet];
    return ([self rangeOfCharacterFromSet:numbersCharacterSet].location == NSNotFound);
}

// If my string contains letters and numbers
- (BOOL)containsOnlyNumbersAndLetters{
    NSCharacterSet *numAndLetterCharSet = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
    return ([self rangeOfCharacterFromSet:numAndLetterCharSet].location == NSNotFound);
}

// If my string is available in particular array
- (BOOL)isInThisarray:(NSArray*)array{
    for(NSString *string in array) {
        if([self isEqualToString:string]) {
            return YES;
        }
    }
    return NO;
}

// Get String from array
+ (NSString *)getStringFromArray:(NSArray *)array{
    return [array componentsJoinedByString:@""];
}

+ (NSString *)getUrlStringFromArray:(NSArray *)array {
    return [array componentsJoinedByString:@"&"];
}

// Convert Array from my String
- (NSArray *)getArray{
    return [self componentsSeparatedByString:@""];
}

// Get My Application Version number
+ (NSString *)getMyApplicationVersion {
    NSDictionary *info = [[NSBundle mainBundle] infoDictionary];
    NSString *version = [info objectForKey:@"CFBundleVersion"];
    return version;
}

// Get My Application name
+ (NSString *)getMyApplicationName {
    NSDictionary *info = [[NSBundle mainBundle] infoDictionary];
    NSString *name = [info objectForKey:@"CFBundleDisplayName"];
    return name;
}


// Convert string to NSData
- (NSData *)convertToData {
    return [self dataUsingEncoding:NSUTF8StringEncoding];
}

// Get String from NSData
+ (NSString *)getStringFromData:(NSData *)data {
    return [[NSString alloc] initWithData:data
                                 encoding:NSUTF8StringEncoding];
    
}

// Is Valid Email
- (BOOL)isValidEmail{
    NSString *regex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSPredicate *emailTestPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    return [emailTestPredicate evaluateWithObject:self];
}

// Is Valid Phone
- (BOOL)isVAlidPhoneNumber {
    NSString *MOBILE = @"^1(3[0-9]|4[57]|5[0-35-9]|8[0-9]|7[0-9]|6[6])\\d{8}$";
    NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
    return [regextestmobile evaluateWithObject:self];
}

- (BOOL)isMobileNumber{
    /**
     * 手机号码
     * 移动：134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
     * 联通：130,131,132,152,155,156,185,186
     * 电信：133,1349,153,180,189
     */
    NSString * MOBILE = @"^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$";
    /**
     10         * 中国移动：China Mobile
     11         * 134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
     12         */
    NSString * CM = @"^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\d)\\d{7}$";
    /**
     15         * 中国联通：China Unicom
     16         * 130,131,132,152,155,156,185,186
     17         */
    NSString * CU = @"^1(3[0-2]|5[256]|8[56])\\d{8}$";
    /**
     20         * 中国电信：China Telecom
     21         * 133,1349,153,180,189
     22         */
    NSString * CT = @"^1((33|53|8[09])[0-9]|349)\\d{7}$";
    /**
     25         * 大陆地区固话及小灵通
     26         * 区号：010,020,021,022,023,024,025,027,028,029
     27         * 号码：七位或八位
     28         */
    // NSString * PHS = @"^0(10|2[0-5789]|\\d{3})\\d{7,8}$";
    
    NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
    NSPredicate *regextestcm = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM];
    NSPredicate *regextestcu = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU];
    NSPredicate *regextestct = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT];
    
    if (([regextestmobile evaluateWithObject:self] == YES)
        || ([regextestcm evaluateWithObject:self] == YES)
        || ([regextestct evaluateWithObject:self] == YES)
        || ([regextestcu evaluateWithObject:self] == YES))
    {
        return YES;
    }
    else
    {
        return NO;
    }
}

// Is Valid URL
- (BOOL)isValidUrl {
    NSString *regex =@"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+";
    NSPredicate *urlTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
    return [urlTest evaluateWithObject:self];
}




//普通字符串转换为十六进制的。

+ (NSString *)hexStringFromString:(NSString *)string{
    NSData *myD = [string dataUsingEncoding:NSUTF8StringEncoding];
    Byte *bytes = (Byte *)[myD bytes];
    //下面是Byte 转换为16进制。
    NSString *hexStr=@"";
    
    
//    for(int i=0;i<[myD length];i++)
//    {
//        NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];///16进制数
//        if([newHexStr length]==1)
//            hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr];
//        else
//            hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr];
//    }
    
    
    hexStr = [NSString stringWithFormat:@"%s",bytes];
    return hexStr;
    
}


//转为小写字母
+(NSString *)toLower:(NSString *)str{
    for (NSInteger i=0; i<str.length; i++) {
        if ([str characterAtIndex:i]>='A'&[str characterAtIndex:i]<='Z') {
            //A  65  a  97
            char  temp=[str characterAtIndex:i]+32;
            NSRange range=NSMakeRange(i, 1);
            str=[str stringByReplacingCharactersInRange:range withString:[NSString stringWithFormat:@"%c",temp]];
        }
    }
    return str;
}

//转为大写字母
+(NSString *)toUpper:(NSString *)str{
    for (NSInteger i=0; i<str.length; i++) {
        if ([str characterAtIndex:i]>='a'&[str characterAtIndex:i]<='z') {
            //A  65  a  97
            char  temp=[str characterAtIndex:i]-32;
            NSRange range=NSMakeRange(i, 1);
            str=[str stringByReplacingCharactersInRange:range withString:[NSString stringWithFormat:@"%c",temp]];
        }
    }
    return str;
}



- (NSString *)md5 {
    NSString *md5string = [NSString string];
    const char *cStr = [self cStringUsingEncoding:NSUTF8StringEncoding];
    unsigned char buffer[CC_MD5_DIGEST_LENGTH];
    
    CC_MD5(cStr, (CC_LONG)strlen(cStr), buffer);
    
    int i;
    for (i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
        md5string = [md5string stringByAppendingString:[NSString stringWithFormat:@"%02x", buffer[i]]];
    
    return md5string;
}

+(BOOL) isValidateMobile:(NSString *)mobile {
    //手机号以13， 15，18开头，八个 \d 数字字符
    NSString *phoneRegex = @"^((13[0-9])|(15[^4,\\D])|(18[0,0-9]))\\d{8}$";
    NSPredicate *phoneTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",phoneRegex];
    //NSLog(@"phoneTest is %@",phoneTest);
    return [phoneTest evaluateWithObject:mobile];
}

//判断是否为整形：
+ (BOOL)isPureInt:(NSString*)string {
    NSScanner* scan = [NSScanner scannerWithString:string];
    int val;
    return[scan scanInt:&val] && [scan isAtEnd];
}

//判断是否为浮点形：
+ (BOOL)isPureFloat:(NSString*)string {
    NSScanner* scan = [NSScanner scannerWithString:string];
    float val;
    return[scan scanFloat:&val] && [scan isAtEnd];
}

#pragma mark - 身份证识别
+ (BOOL) validateIdentityCard: (NSString *)identityCard
{
    BOOL flag;
    if (identityCard.length <= 0) {
        flag = NO;
        return flag;
    }
    NSString *regex2 = @"^(\\d{14}|\\d{17})(\\d|[xX])$";
    NSPredicate *identityCardPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex2];
    return [identityCardPredicate evaluateWithObject:identityCard];
}

/**
 @brief 时间格式转化
 @ param date
 @ param type
 */
+ (NSString *)timeDateFormatter:(NSDate *)date type:(int)type {

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    
//    [dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
    
    switch (type) {
        case 1:
            [dateFormatter setDateFormat:@"yyyy"];
            break;
        case 2:
            [dateFormatter setDateFormat:@"yyyy年MM月"];
            break;
        case 3:
            [dateFormatter setDateFormat:@"yyyy-MM-dd"];
            break;
        case 4:
            [dateFormatter setDateFormat:@"hh"];
            break;
        case 5:
            [dateFormatter setDateFormat:@"mm"];
            break;
        case 6:
            [dateFormatter setDateFormat:@"ss"];
            break;
        case 7:
            [dateFormatter setDateFormat:@"a"];
            break;
        case 8:
            [dateFormatter setDateFormat:@"MM"];
            break;
        case 9:
            [dateFormatter setDateFormat:@"dd"];
            break;
        case 10:
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm"];
            break;
        case 11:
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            break;
        case 12:
            [dateFormatter setDateFormat:@"HH:mm"];
            break;
        case 13:
            [dateFormatter setDateFormat:@"yyyyMMddHHmm"];
            break;
        case 14:
            [dateFormatter setDateFormat:@"MM-dd"];
            break;
        case 15:
            [dateFormatter setDateFormat:@"yyyy年MM月dd日 HH:mm"];
            break;
        case 16:
            [dateFormatter setDateFormat:@"yyyyMMdd"];
            break;
        case 17:
            [dateFormatter setDateFormat:@"yyyyMMddHHmmss"];
            break;
        case 18:
            [dateFormatter setDateFormat:@"MM-dd HH:mm"];
            break;
        case 19:
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH"];
            break;
        case 20:
            [dateFormatter setDateFormat:@"yyyy年MM月dd日"];
            break;
        case 21:
            [dateFormatter setDateFormat:@"MM月dd日"];
            break;
        case 22:
            [dateFormatter setDateFormat:@"MM月dd日 EEEE"];
            break;
        case 23:
            [dateFormatter setDateFormat:@"HH"];
        default:
            break;
    }
    //    设置东8区
    [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:8*3600]];
    NSString* timeString = [dateFormatter stringFromDate:date];
//    [dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
//    NSString *timeString = [NSString stringWithFormat:@"%@",[dateFormatter stringFromDate:date]];
    
    return timeString;
}

#pragma mark - 计算显示字符串的宽度或高度

+ (CGSize)getSizeOfTextInfo:(NSString *)textInfo andFontSize:(CGFloat)fontSize andWidth:(CGFloat)width
{
    CGSize size = CGSizeMake(width, CGFLOAT_MAX);
    
    if ((!textInfo) || (textInfo.length == 0)) {
        size.height = 0;
        size.width = 0;
        return size;
    }
    CGRect rect = [textInfo boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObject:FONT_PM(fontSize) forKey:NSFontAttributeName] context:Nil];
    return rect.size;
}

+ (CGSize)getSizeOfTextInfo:(NSString *)textInfo andFont:(UIFont *)font andWidth:(CGFloat)width
{
    CGSize size = CGSizeMake(width, CGFLOAT_MAX);
    
    if ((!textInfo) || (textInfo.length == 0)) {
        size.height = 0;
        size.width = 0;
        return size;
    }
    CGRect rect = [textInfo boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName] context:Nil];
    return rect.size;
}

- (CGSize)sizeWithMyFont:(UIFont *)font {
    NSDictionary* attribs = @{NSFontAttributeName:font};
    return ([self sizeWithAttributes:attribs]);
}

- (CGSize)sizeWithMyFont:(UIFont *)font size:(CGSize)size {
    CGRect textRect = [self boundingRectWithSize:size
                                         options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin
                                      attributes:@{NSFontAttributeName:font}
                                         context:nil];
    return textRect.size;
}


+ (BOOL)judgeIdentityStringValid:(NSString *)identityString {
    
    if (identityString.length != 18) return NO;
    // 正则表达式判断基本 身份证号是否满足格式
    NSString *regex = @"^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X)$";
    //  NSString *regex = @"^(^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$)|(^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])((\\d{4})|\\d{3}[Xx])$)$";
    NSPredicate *identityStringPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
    //如果通过该验证，说明身份证格式正确，但准确性还需计算
    if(![identityStringPredicate evaluateWithObject:identityString]) return NO;
    
    //** 开始进行校验 *//
    
    //将前17位加权因子保存在数组里
    NSArray *idCardWiArray = @[@"7", @"9", @"10", @"5", @"8", @"4", @"2", @"1", @"6", @"3", @"7", @"9", @"10", @"5", @"8", @"4", @"2"];
    
    //这是除以11后，可能产生的11位余数、验证码，也保存成数组
    NSArray *idCardYArray = @[@"1", @"0", @"10", @"9", @"8", @"7", @"6", @"5", @"4", @"3", @"2"];
    
    //用来保存前17位各自乖以加权因子后的总和
    NSInteger idCardWiSum = 0;
    for(int i = 0;i < 17;i++) {
        NSInteger subStrIndex = [[identityString substringWithRange:NSMakeRange(i, 1)] integerValue];
        NSInteger idCardWiIndex = [[idCardWiArray objectAtIndex:i] integerValue];
        idCardWiSum+= subStrIndex * idCardWiIndex;
    }
    
    //计算出校验码所在数组的位置
    NSInteger idCardMod=idCardWiSum%11;
    //得到最后一位身份证号码
    NSString *idCardLast= [identityString substringWithRange:NSMakeRange(17, 1)];
    //如果等于2，则说明校验码是10，身份证号码最后一位应该是X
    if(idCardMod==2) {
        if(![idCardLast isEqualToString:@"X"]||[idCardLast isEqualToString:@"x"]) {
            return NO;
        }
    }
    else{
        //用计算出的验证码与最后一位身份证号码匹配，如果一致，说明通过，否则是无效的身份证号码
        if(![idCardLast isEqualToString: [idCardYArray objectAtIndex:idCardMod]]) {
            return NO;
        }
    }
    return YES;
}
- (NSMutableAttributedString *)addAttributeWithColor:(UIColor *)textColor forRange:(NSRange)rang
{
    NSMutableAttributedString * str = [[NSMutableAttributedString alloc]initWithString:self];
    [str addAttribute:NSForegroundColorAttributeName value:textColor range:rang];
    return str;
}
- (NSMutableAttributedString *)addAttributeWithFont:(CGFloat)textFont andTextColor:(UIColor *)textColor forRange:(NSRange)rang
{
    NSMutableAttributedString * str = [[NSMutableAttributedString alloc]initWithString:self];
    [str addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:textFont] range:rang];
    if (textColor) {
        [str addAttribute:NSForegroundColorAttributeName value:textColor range:rang];
    }
    return str;
}
+ (NSString *)ossSizeWithOriginStr:(NSString *)originStr withWidth:(NSInteger)width {
    NSInteger wid = width*2;
    if (![originStr containsString:@"x-oss-process"]) {
        return [NSString stringWithFormat:@"%@?x-oss-process=image/resize,w_%@",originStr,@(wid)];
    }
    return originStr;
}

+ (NSString *)plistVersion{

    //获取当前版本号
    NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"];
    NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
    NSString *version = [dictionary objectForKey:@"CFBundleShortVersionString"];
    
    return version;

}


- (NSString *)encryptedPhone{

    //手机号 (做*处理)
    NSMutableString * rStr = [[NSMutableString alloc]init];
    for (int i = 0; i<4; i++) {
        [rStr appendString:@"*"];
    }
    if (self.length < 7) {
        return @"****";
    }
    
    return [self stringByReplacingCharactersInRange:NSMakeRange(3, 6) withString:rStr];
}


+ (NSString *)md5EncryptRandomNumber {
    int x = arc4random() % 1000000000000000;
    NSString *randomNum = [NSString stringWithFormat:@"%@",@(x)];
    //大写的加密
    const char *cStr = [randomNum UTF8String];
    unsigned char result[16];
    NSNumber *num = [NSNumber numberWithUnsignedLong:strlen(cStr)];
    CC_MD5( cStr,[num intValue], result );
    return [[NSString stringWithFormat:
             @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
             result[0], result[1], result[2], result[3],
             result[4], result[5], result[6], result[7],
             result[8], result[9], result[10], result[11],
             result[12], result[13], result[14], result[15]
             ] uppercaseString];
}


@end
